package com.hxtec.polaris.service.impl;

import com.hxtec.polaris.commons.api.vo.Result;
import com.hxtec.polaris.commons.constant.Code;
import com.hxtec.polaris.commons.constant.GlobalVar;
import com.hxtec.polaris.commons.constant.Log;
import com.hxtec.polaris.commons.constant.Msg;
import com.hxtec.polaris.commons.contants.CommonContants;
import com.hxtec.polaris.commons.dto.OrderInfoDto;
import com.hxtec.polaris.commons.dto.Page;
import com.hxtec.polaris.commons.exception.MyException;
import com.hxtec.polaris.entity.ShopAddress;
import com.hxtec.polaris.entity.ShopCartItem;
import com.hxtec.polaris.entity.ShopOrder;
import com.hxtec.polaris.entity.ShopOrderItem;
import com.hxtec.polaris.entity.ShopUser;
import com.hxtec.polaris.mapper.ShopCartItemMapper;
import com.hxtec.polaris.mapper.ShopOrderItemMapper;
import com.hxtec.polaris.mapper.ShopOrderMapper;
import com.hxtec.polaris.mapper.ShopProductVariantMapper;
import com.hxtec.polaris.service.CartItemService;
import com.hxtec.polaris.service.OrderManagerService;
import com.hxtec.polaris.service.OrderService;
import com.hxtec.polaris.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

/**
 * @Describtion 订单相关service
 * @Author yonyong
 * @Date 2019/12/3 14:48
 * @Version 1.0.0
 **/
@Service
@Transactional
public class OrderServiceImpl implements OrderService{

    private final static String LOG_CLASS_NAME = "OrderServiceImpl";
    private final static String LOG_METHOD_GET_ORDER = "getOrder";
    private final static String LOG_METHOD_GET_PRICE = "getPrice";
    private final static String LOG_METHOD_EXTEND_RECEIVE = "extendedReceipt";
    private final static String LOG_METHOD_CONFIRM_RECEIVE = "confirmReceipt";
    private final static String LOG_METHOD_DELETE_ORDER = "deleteOrder";
    private final static String LOG_METHOD_CANCEL_ORDER = "cancelOrder";
    private final static String LOG_METHOD_RATE_ORDER = "rateOrder";

    @Resource
    private ShopOrderItemMapper shopOrderItemMapper;
    @Resource
    private ShopOrderMapper shopOrderMapper ;
    @Resource
    private UserService userService;

    @Resource
    private CartItemService cartItemService;

    @Resource
    private ShopCartItemMapper cartItemMapper;

    @Autowired
    private OrderManagerService orderManagerService;


    @Override
    public Object getOrder(Integer state, Integer pageNow, Integer rows) {
        //state -1 全部订单  0 待付款 1 待发货订单 2待收货订单 3待评价订单 4 交易成功订单 5 已关闭订单
        try {
            return doGetOrder(state,pageNow,rows);
        }catch (Exception e){
            String params = "state="+state+";pageNow="+pageNow+";rows="+rows;
            String LOG_MSG = MessageFormat.format(Log.PATTERN_LOG,Log.DELETE,LOG_CLASS_NAME,LOG_METHOD_GET_ORDER,params);
            throw new MyException(Result.error(Code.FAIL_4601, Msg.COMMON_FAIL),LOG_MSG);
        }
    }


    /**
     * 执行查询订单  state -1 全部订单  0 待付款 1 待发货订单 2待收货订单 3待评价订单 4 交易成功订单 5 已关闭订单
     * @param state
     * @param pageNow
     * @param rows
     * @return
     */
    private Result doGetOrder(Integer state, Integer pageNow, Integer rows) {
        String usrId = String.valueOf(userService.getUserInfo().getId());
        //分页信息
        int count = shopOrderMapper.getOrderCount(usrId,state);
        Page page = new Page(count,pageNow,rows);

        //数据信息
        //分页查出订单信息
        List<Map<String,Object>> list = shopOrderMapper.getOrder(usrId,state,(pageNow-1)*rows,rows);
        if (null!=list && list.size()>0){
            for (Map<String,Object> map1 : list){
                //将查询出的每个订单的商品信息查出放到订单的map里
                Integer orderId = (Integer) map1.get("id");
                List<Map<String,Object>> itemList = shopOrderMapper.getOrderItemsByOneOrder(usrId,orderId);
                map1.put("goods",itemList);
            }
        }
        return Result.ok(page,list);
    }

    @Override
    public Map<String, Object> submitOrder(OrderInfoDto orderInfoDto) {
        String phone="12345678900";
        ShopUser userInfo=userService.getUserInfoByPhone(phone);
        Map<String,Object> map=new HashMap<>();
        //未登录
        if(StringUtils.equals("anonymousUser",phone)){
            map.put(CommonContants.STATUS,"error");
            map.put(CommonContants.MESSAGE,"userError");
            return map;
        }
        ShopAddress shopAddress=new ShopAddress();
        BeanUtils.copyProperties(orderInfoDto.getAddress(),shopAddress);
        List cartIds = orderInfoDto.getCartIds();
        //地址信息
        ShopOrder shopOrder =ShopOrder.builder()
                .autoConfirmDay(7)
                .createTime(new Date())
                .memberId(userInfo.getId())
                .state(0)
                .receiverName(shopAddress.getComment1())
                .receiverPhone(shopAddress.getComment2())
                .addressDetail(shopAddress.getRegion()+shopAddress.getDetail())
                .confirmStatus(0).build();
        //从购物车中查找订单信息
        List<ShopCartItem> shopCartItemList =new ArrayList<>();
        cartIds.forEach(id->{
            ShopCartItem shopCartItem = cartItemMapper.selectByPrimaryKey(id);
            shopCartItemList.add(shopCartItem);
        });
        List<ShopOrderItem> shopOrderItems=new ArrayList<>();
        //根据购物车数据生成订单数据
        BigDecimal  price=new BigDecimal("0.0");
        BigDecimal  discountPrice=new BigDecimal("0.0");
        for (ShopCartItem cartItem:shopCartItemList){
            ShopOrderItem shopOrderItem=ShopOrderItem.builder()
                    .productId(cartItem.getProductId())
                    .productPic(cartItem.getProductPic())
                    .productName(cartItem.getProductName())
                    .productIntroduce(cartItem.getProductSubTitle())
                    .productPrice(cartItem.getPrice())
                    .discountPrice(cartItem.getDiscountprice())
                    .productQuantity(cartItem.getQuantity())
                    .productSkuId(cartItem.getProductSkuId())
                    .productCategoryId(cartItem.getProductCategoryId())
                    .productAttr(cartItem.getProductAttr())
                    .isDelete("N").build();
            if(null !=cartItem.getPrice()){
                price=price.add(cartItem.getPrice().multiply(BigDecimal.valueOf(cartItem.getQuantity())));
            }
            if(null !=cartItem.getDiscountprice()){
                discountPrice=discountPrice.add(cartItem.getDiscountprice().multiply(BigDecimal.valueOf(cartItem.getQuantity())));
            }
            shopOrderItems.add(shopOrderItem);
        }

        shopOrder.setShopOrderItems(shopOrderItems);
        shopOrder.setTotalPrice(price);
        shopOrder.setDiscountPrice(discountPrice);
        shopOrder.setPayPrice(price);
        this.saveOrder(shopOrder);
        // 删除购物车数据
        cartItemService.delCartById(cartIds);
        map.put(CommonContants.STATUS,"success");
        return map;
    }

    @Override
    public Optional<ShopOrder> getOne(String orderId) {
        return Optional.empty();
    }

    @Override
    public Object getPrice(int oid) {
        try {
            Map<String,Object> orderMap = shopOrderMapper.getPriceByOrderId(oid,String.valueOf(userService.getUserInfo().getId()));
            return Result.ok(orderMap);
        }catch (Exception e){
            String params = "oid="+oid;
            String LOG_MSG = MessageFormat.format(Log.PATTERN_LOG,Log.QUERY,LOG_CLASS_NAME,LOG_METHOD_GET_PRICE,params);
            throw new MyException(Result.error(Code.FAIL_4601, Msg.COMMON_FAIL),LOG_MSG);
        }
    }

    @Override
    public Object extendedReceipt(ShopOrder shopOrder) {
        try{
            doExtendReceipt(shopOrder);
            return Result.ok();
        }catch (Exception e){
            String params = "shopOrder="+shopOrder.toString();
            String LOG_MSG = MessageFormat.format(Log.PATTERN_LOG,Log.UPDATE,LOG_CLASS_NAME,LOG_METHOD_EXTEND_RECEIVE,params);
            throw new MyException(Result.error(Code.FAIL_4601, Msg.COMMON_FAIL),LOG_MSG);
        }
    }

    @Override
    public Object confirmReceipt(ShopOrder shopOrder) {
        try{
            doConfirmReceipt(shopOrder);
            return Result.ok();
        }catch (Exception e){
            String params = "shopOrder="+shopOrder.toString();
            String LOG_MSG = MessageFormat.format(Log.PATTERN_LOG,Log.UPDATE,LOG_CLASS_NAME,LOG_METHOD_CONFIRM_RECEIVE,params);
            throw new MyException(Result.error(Code.FAIL_4601, Msg.COMMON_FAIL),LOG_MSG);
        }
    }

    @Override
    public Object deleteOrder(ShopOrder shopOrder) {
        try{
            doDeleteOrder(shopOrder);
            return Result.ok();
        }catch (Exception e){
            String params = "shopOrder="+shopOrder.toString();
            String LOG_MSG = MessageFormat.format(Log.PATTERN_LOG,Log.DELETE,LOG_CLASS_NAME,LOG_METHOD_DELETE_ORDER,params);
            throw new MyException(Result.error(Code.FAIL_4601, Msg.COMMON_FAIL),LOG_MSG);
        }
    }

    @Override
    public Object cancelOrder(ShopOrder shopOrder) {
        try{
            doCancelOrder(shopOrder);
            return Result.ok();
        }catch (Exception e){
            String params = "shopOrder="+shopOrder.toString();
            String LOG_MSG = MessageFormat.format(Log.PATTERN_LOG,Log.UPDATE,LOG_CLASS_NAME,LOG_METHOD_CANCEL_ORDER,params);
            throw new MyException(Result.error(Code.FAIL_4601, Msg.COMMON_FAIL),LOG_MSG);
        }
    }

    @Override
    public Object rateOrder(int id,int state, String content) {
        try{
            doRateOrder(id,state,content);
            return Result.ok();
        }catch (Exception e){
            String params = "orderid="+id+";content="+content;
            String LOG_MSG = MessageFormat.format(Log.PATTERN_LOG,Log.UPDATE,LOG_CLASS_NAME,LOG_METHOD_RATE_ORDER,params);
            throw new MyException(Result.error(Code.FAIL_4601, Msg.COMMON_FAIL),LOG_MSG);
        }
    }

    /**
     * 执行订单评价
     * @param id    订单id
     * @param state    订单state
     * @param content   评价内容
     */
    private void doRateOrder(int id, int state,String content) {
        //只有订单待评价的情况下才可以评价订单
        if (state == GlobalVar.ORDER_REPLYING){
            //执行更新
            shopOrderMapper.doRateOrder(id,String.valueOf(userService.getUserInfo().getId()),GlobalVar.ORDER_SUCCESS,new Date());
        }
    }

    /**
     * 执行订单取消 state设置为5 已关闭状态
     * @param shopOrder
     */
    private void doCancelOrder(ShopOrder shopOrder) {
        //只有待付款情况下才可以取消订单
        if (shopOrder.getState() == GlobalVar.ORDER_PAYING){
            //执行更新
            shopOrderMapper.doCancelOrder(shopOrder.getId(),String.valueOf(userService.getUserInfo().getId()),GlobalVar.ORDER_CLOSED,new Date());
            //添加操作记录
            orderManagerService.addOrderRecord(shopOrder.getId(),GlobalVar.OPERATER_USER,GlobalVar.ORDER_CLOSED,"用户取消本订单");
        }
    }

    /**
     * 执行订单删除 isdeleted Y
     * @param shopOrder
     */
    private void doDeleteOrder(ShopOrder shopOrder) {
        //只有订单状态为已关闭(5)、待评价(3)、交易完成(4)情况下才可以删除
        if (shopOrder.getState() == GlobalVar.ORDER_CLOSED
                || shopOrder.getState() == GlobalVar.ORDER_REPLYING
                || shopOrder.getState() == GlobalVar.ORDER_SUCCESS){
            //执行更新
            shopOrderMapper.doDeleteOrder(shopOrder.getId(),String.valueOf(userService.getUserInfo().getId()),new Date());
            //添加操作记录
            orderManagerService.addOrderRecord(shopOrder.getId(),GlobalVar.OPERATER_USER,GlobalVar.ORDER_DELETED,"用户删除本订单");
        }
    }

    /**
     * 执行确认收货
     * @param shopOrder
     */
    private void doConfirmReceipt(ShopOrder shopOrder) {
        //只有待收货情况下才可以确认收货
        if (shopOrder.getState() == GlobalVar.ORDER_RECIIVEING){
            //执行更新
            shopOrderMapper.doConfirmReceipt(shopOrder.getId(),String.valueOf(userService.getUserInfo().getId()),GlobalVar.ORDER_SUCCESS,new Date());
            //添加操作记录
            orderManagerService.addOrderRecord(shopOrder.getId(),GlobalVar.OPERATER_USER,GlobalVar.ORDER_SUCCESS,"用户确认收货");
        }
    }

    /**
     * 执行延时收货
     * @param shopOrder
     */
    private void doExtendReceipt(ShopOrder shopOrder) {
        //只有待收货情况下才可以延时收货
        if (shopOrder.getState() == GlobalVar.ORDER_RECIIVEING){
            //执行更新
            shopOrderMapper.doExtendReceipt(shopOrder.getId(),String.valueOf(userService.getUserInfo().getId()),GlobalVar.DELAY_TIME,new Date());
            ShopOrder tempObj = shopOrderMapper.getOrderById(shopOrder.getId());
            //添加操作记录
            orderManagerService.addOrderRecord(shopOrder.getId(),GlobalVar.OPERATER_USER,tempObj.getState(),"用户申请延时收货");
        }
    }

    private void saveOrder(ShopOrder shopOrder) {
        //订单表
        shopOrderMapper.insertSelective(shopOrder);
        Integer id = shopOrder.getId();
        //订单明细表
        List<ShopOrderItem> shopOrderItems = shopOrder.getShopOrderItems();
        shopOrderItems.forEach(shopOrderItem -> {
            shopOrderItem.setOrderId(id);
            shopOrderItemMapper.insertSelective(shopOrderItem);

        });
        //添加操作记录
        orderManagerService.addOrderRecord(id,GlobalVar.OPERATER_USER,GlobalVar.ORDER_PAYING,"用户创建本订单");
    }

    private String getUser(){
        return SecurityContextHolder.getContext().getAuthentication().getName();
    }

}
